package com.yy.finvideoplayer.danmu

import com.yy.finvideoplayer.model.PlayerOptions

/**
 * @Description: DanmuEmitter
 * @Author: yiw89
 * @CreateDate: 2025/9/15 11:54
 * @Version: 1.0
 */class DanmuEmitter {
    private val danmuList = ArrayList<PlayerOptions.DanmakuItem>()
    var isActive = false
    private var paused = false

    fun reload(list: List<PlayerOptions.DanmakuItem>) {
        danmuList.clear()
        danmuList.addAll(list)
    }

    fun pause() {
        paused = true
    }

    fun resume() {
        paused = false
    }

    fun insertDanmakuItem(DanmakuItem: PlayerOptions.DanmakuItem) {
        fun binarySearchIndex(dmItem: PlayerOptions.DanmakuItem, from: Int, end: Int): Int {
            if (danmuList.isEmpty()) {
                return -1
            }
            if (danmuList.size == 1) {
                return if (dmItem.timeInMills >= danmuList[0].timeInMills) {
                    return 1
                } else {
                    0
                }
            }
            if (end - from == 1) {
                return end
            }
            val binaryIndex = (from + end) / 2
            val binaryDanmu = danmuList[binaryIndex]

            val binaryIndex1 = binaryIndex + 1
            val binaryDanmu1 = danmuList[binaryIndex1]

            if (dmItem.timeInMills in binaryDanmu.timeInMills until binaryDanmu1.timeInMills) {
                return binaryIndex1
            }

            return if (DanmakuItem.timeInMills >= binaryDanmu.timeInMills) {
                binarySearchIndex(dmItem, binaryIndex, end)
            } else {
                binarySearchIndex(dmItem, from, binaryIndex)
            }
        }

        val theIndex = binarySearchIndex(DanmakuItem, 0, danmuList.size - 1)
        if (theIndex < 0) {
            danmuList.add(DanmakuItem)
        } else {
            danmuList.add(theIndex, DanmakuItem)
        }
    }

    fun emit(
        timeInMillsFrom: Int,
        timeInMillsTo: Int,
        callback: (dms: List<PlayerOptions.DanmakuItem>) -> Unit
    ) {
        if (!isActive) {
            return
        }
        if (paused) {
            return
        }
        callback.invoke(danmuList.filter {
            it.timeInMills in timeInMillsFrom until timeInMillsTo
        })
    }

    fun clean() {
        danmuList.clear()
    }
}